package com.example.hibernate;


import java.util.List;


import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Projections;

import com.example.pagination.PagHelper;

/**
 * Query By Criteria 数据访问基础对象(QBCBaseHibernateDAO)
 * 
 * @author JianpengTong
 * @since 2009-6-30
 * @version 1.0
 */
public class HibernateBaseDAO {
	// protected static final Logger log =
	// Logger.getLogger(HibernateBaseDAO.class);
	// protected Log log = null;
	protected Logger log = null;
	protected Class clazz = null;
	protected Session session = null;
	protected Transaction trans = null;

	/**
	 * 保存对象
	 * */
	public boolean save(Object obj) {
		log.info("保存对象: " + clazz.getName());
		try {
			trans = session.beginTransaction();
			session.save(obj);
			trans.commit();
			log.info("保存成功...");
			return true;
		} catch (HibernateException e) {
			if (trans != null)
				trans.rollback();
			log.warn("保存失败!!,事务回滚...", e);
			return false;
		}
	}

	/**
	 * 保存或更新对象
	 * */
	public boolean update(Object obj) {
		log.info("更新对象: " + clazz.getName());
		try {
			if (session.contains(obj))
				session.evict(obj);
			trans = session.beginTransaction();
			session.update(obj);
			trans.commit();
			log.info("更新成功...");
			return true;
		} catch (HibernateException e) {
			if (trans != null)
				trans.rollback();
			log.warn("更新失败!!,事务回滚...", e);
			return false;
		}
	}

	/**
	 * 保存或更新对象
	 * */
	public boolean saveOrUpdate(Object obj) {
		log.info("保存或更新对象: " + clazz.getName());
		try {
			if (session.contains(obj))
				session.evict(obj);
			trans = session.beginTransaction();
			session.saveOrUpdate(obj);
			trans.commit();
			session.flush();
			log.info("保存或更新成功...");
			return true;
		} catch (HibernateException e) {
			if (trans != null)
				trans.rollback();
			log.warn("保存或更新失败!!,事务回滚...", e);
			return false;
		}
	}

	/**
	 * 合并对象<br/>
	 * 保存或更新
	 * */
	public Object mergeObject(Object obj) {
		log.info("合并对象：" + clazz.getName());
		try {
			trans = session.beginTransaction();
			Object object = session.merge(obj);
			trans.commit();
			log.info("合并对象成功...");
			return object;
		} catch (HibernateException e) {
			if (trans != null)
				trans.rollback();
			log.warn("合并对象失败!!,事务回滚...", e);
			return null;
		}
	}

	/**
	 * 删除对象
	 * */
	public boolean delete(Object obj) {
		log.info("删除对象: " + clazz.getName());
		try {
			if (session.contains(obj))
				session.evict(obj);
			trans = session.beginTransaction();
			session.delete(obj);
			trans.commit();
			log.info("删除成功...");
			return true;
		} catch (HibernateException e) {
			if (trans != null)
				trans.rollback();
			log.warn("删除失败!!,事务回滚...", e);
			return false;
		}
	}

	/**
	 * 根据对象 Id 删除对象
	 * */
	public boolean deleteById(String id) {
		log.info("删除标识为 " + id + " 的对象: " + clazz.getName());
		try {
			trans = session.beginTransaction();
			Object obj = session.load(clazz, id);
			session.delete(obj);
			trans.commit();
			log.info("删除成功...");
			return true;
		} catch (HibernateException e) {
			if (trans != null)
				trans.rollback();
			log.warn("删除失败!!,事务回滚...", e);
			return false;
		}

	}

	/**
	 * 获取一个对象
	 * */
	public Object getObject() {
		log.info("获取一个对象:" + clazz.getName());
		try {
			Criteria criteria = session.createCriteria(clazz).setMaxResults(1);
			Object obj = criteria.uniqueResult();
			log.info("获取对象成功...");
			return obj;
		} catch (HibernateException e) {
			log.warn("获取对象失败...", e);
			return null;
		}
	}

	/**
	 * 获取具有指定 Id 值的一个对象.
	 * */
	public Object getObjectById(String id) {
		log.info("获取标识为 " + id + " 的对象: " + clazz);
		try {
			Object obj = session.get(clazz, id);
			log.info("获取对象成功...");
			return obj;
		} catch (HibernateException e) {
			log.warn("获取对象失败...", e);
			return null;
		}
	}

	/**
	 * 获取所有对象
	 * */
	public List getObjects() {
		log.info("获取所有对象: " + clazz.getName());
		try {
			List list = session.createCriteria(clazz).list();
			log.info("成功获取所有对象!!,集合大小: " + list.size());
			return list;
		} catch (HibernateException e) {
			log.warn("获取所有对象操作失败...", e);
			return null;
		}
	}

	/**
	 * 分页获取对象
	 * */
	public List getObjects(PagHelper pag) {
		log.info("分页获取对象: " + clazz);
		try {
			Criteria crit = session.createCriteria(clazz);
			crit.setProjection(Projections.rowCount());

			pag.setRowsCount(Integer.parseInt(crit.uniqueResult().toString()));
			crit.setProjection(null);
			crit.setFirstResult(pag.getStartRow());
			crit.setMaxResults(pag.getEndRow());
			List list = crit.list();
			log.info("获取第 " + pag.getPageIndex() + " 页对象集合成功!!,记录为:"
					+ (pag.getStartRow() + 1) + " ~ " + (pag.getEndRow() + 1)
					+ ", 集合大小: " + list.size());
			return list;
		} catch (HibernateException e) {
			log.warn("获取第 " + pag.getPageIndex() + " 页对象失败...", e);
			return null;
		}
	}

	/**
	 * 获取具有指定属性值的所有对象
	 * */
	public List getObjectByProperty(String propertyName, Object value) {
		log.info("获取 " + propertyName + " 属性值为 " + value + " 的所有对象: " + clazz);
		try {
			List list = session.createCriteria(clazz).add(
					Expression.eq(propertyName, value)).list();
			log.info("获取所有对象成功!!,集合大小: " + list.size());
			return list;
		} catch (HibernateException e) {
			log.warn("获取所有对象失败...", e);
			return null;
		}
	}

	/**
	 * 获取所有具有和样例对象所有非空属性值相同的对象集合
	 * */
	public List getObjectByExample(Object obj) {
		log.info("获取所有具有和样例对象所有非空属性值相同的对象集合: " + clazz.getName());
		try {
			List list = session.createCriteria(clazz).add(Example.create(obj))
					.list();
			log.info("成功获取对象集合!!,集合大小: " + list.size());
			return list;
		} catch (HibernateException e) {
			log.error("获取对象集合失败...", e);
			return null;
		}
	}

	/**
	 * DetachedCriteria 查询
	 * */
	public List getObjects(DetachedCriteria dCriteria) {
		log.info("开始 DetachedCriteria 查询...");
		try {
			List list = dCriteria.getExecutableCriteria(session).list();
			log.info("成功获取对象集合!!,集合大小: " + list.size());
			return list;
		} catch (HibernateException e) {
			log.error("获取对象集合失败...", e);
			return null;
		}
	}

	/**
	 * DetachedCriteria 分页查询
	 * */
	public List getObjects(DetachedCriteria dCriteria, PagHelper pag) {
		log.info("开始 DetachedCriteria 分页查询...");
		try {
			Criteria crit = dCriteria.getExecutableCriteria(session);
			crit.setProjection(Projections.rowCount());

			pag.setRowsCount(Integer.parseInt(crit.uniqueResult().toString()));
			crit.setProjection(null);
			crit.setFirstResult(pag.getStartRow());
			crit.setMaxResults(pag.getEndRow());
			List list = crit.list();
			log.info("获取第 " + pag.getPageIndex() + " 页对象集合成功!!,记录为:"
					+ (pag.getStartRow() + 1) + " ~ " + (pag.getEndRow() + 1)
					+ ", 集合大小: " + list.size());

			return list;
		} catch (HibernateException e) {
			log.error("获取对象集合失败...", e);
			return null;
		}
	}

	/**
	 * 执行非 select QHL语句.
	 * */
	public int execute(String hql) {
		log.info("执行非 select HQL 语句...\n" + hql);
		try {
			trans = session.beginTransaction();
			Query query = session.createQuery(hql);
			int rows = query.executeUpdate();
			trans.commit();
			log.info("执行成功!!,受影响行数:" + rows);
			return rows;
		} catch (HibernateException e) {
			if (trans != null)
				trans.rollback();
			log.warn("执行失败!!,事务回滚...", e);
			return -1;
		}
	}

	/**
	 * 执行非 select QHL语句.
	 * */
	public int execute(String hql, Object obj) {
		log.info("执行非 select HQL 语句...\n" + hql);
		try {
			trans = session.beginTransaction();
			Query query = session.createQuery(hql);
			query.setProperties(obj);
			int rows = query.executeUpdate();
			trans.commit();
			log.info("执行成功!!,受影响行数:" + rows);
			return rows;
		} catch (HibernateException e) {
			if (trans != null)
				trans.rollback();
			log.warn("执行失败!!,事务回滚...", e);
			return -1;
		}
	}

	/**
	 * 执行非 select QHL语句.
	 * */
	public int execute(String hql, List list) {
		log.info("执行非 select HQL 语句...\n" + hql);
		try {
			trans = session.beginTransaction();
			Query query = session.createQuery(hql);
			for (int i = 0; i < list.size(); i++) {
				query.setParameter(i + 1, list.get(i));
			}
			int rows = query.executeUpdate();
			trans.commit();
			log.info("执行成功!!,受影响行数:" + rows);
			return rows;
		} catch (HibernateException e) {
			if (trans != null)
				trans.rollback();
			log.warn("执行失败!!,事务回滚...", e);
			return -1;
		}
	}

	/**
	 * 执行 select HQL语句.
	 * */
	public List query(String hql) {
		log.info("执行 select HQL语句...\n" + hql);
		try {
			Query query = session.createQuery(hql);
			List list = query.list();
			log.info("执行成功!!,集合大小:" + list.size());
			return list;
		} catch (HibernateException e) {
			log.warn("执行失败...", e);
			return null;
		}
	}

	/**
	 * 执行 select HQL语句.
	 * */
	public List query(String hql, Object obj) {
		log.info("执行 select HQL语句...\n" + hql);
		try {
			Query query = session.createQuery(hql);
			query.setProperties(obj);
			List list = query.list();
			log.info("执行成功!!,集合大小:" + list.size());
			return list;
		} catch (HibernateException e) {
			log.warn("执行失败...", e);
			return null;
		}
	}

	/**
	 * 执行 select HQL语句.
	 * */
	public List query(String hql, List list) {
		log.info("执行 select HQL语句...\n" + hql);
		try {
			Query query = session.createQuery(hql);
			for (int i = 0; i < list.size(); i++) {
				query.setParameter(i + 1, list.get(i));
			}
			List ls = query.list();
			log.info("执行成功!!,集合大小:" + list.size());
			return ls;
		} catch (HibernateException e) {
			log.warn("执行失败...", e);
			return null;
		}
	}
}
